package com.sgj.aspect;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author 沈国纪
 * @date 2021/3/29 9:15
 * 切面
 */
@Aspect
@Component
@Slf4j
public class LogAspect {

	@Pointcut("execution(* com.sgj.controller.*.*(..))")
	public void log() {

	}

	@Before("log()")
	public void doBefore(JoinPoint joinPoint) {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();
		// 请求地址
		String url = request.getRequestURL().toString();
		// 访问 ip
		String ip = request.getRemoteAddr();
		// 调用的方法
		String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
		// 入参
		Object[] args = joinPoint.getArgs();
		RequestLog requestLog = new RequestLog(url, ip, classMethod, args);
		log.info("Request : {}", requestLog);
	}

	@After("log()")
	public void doAfter() {
		log.info("-------doAfter--------");
	}

	@AfterReturning(returning = "result", pointcut = "log()")
	public void doAfterReturn(Object result) {
		log.info("Result : {}" + result);
	}

	@Data
	@AllArgsConstructor
	@NoArgsConstructor
	private class RequestLog {
		/**
		 * 请求 url
		 */
		private String url;

		/**
		 * 访问者 ip
		 */
		private String ip;

		/**
		 * 调用方法 classMethod
		 */
		private String classMethod;

		/**
		 * 参数 args
		 */
		private Object[] args;
	}
}
